#include <stdio.h>
#include "lex.h"
#include "syntax.h"
#define ALIGN_SET 0x100

extern void get_token(void);
extern void skip(int);
extern void expect(char *msg);
extern int token; // 获取的token
extern int tkvalue;
extern Stack global_sym_stack, local_sym_stack;

extern Type char_pointer_type; // 字符串指针
extern Type int_type;          // int 类型
extern Type default_func_type; // 缺省函数类型
int syntax_state;              // 语法状态
int syntax_level;              // 缩进级别

/*
函数调用约定
*/
void function_calling_convention(int *fc)
{
    *fc = KW_CDECL;
    if (token == KW_CDECL || token == KW_STDCALL)
    {
        *fc = token;
        syntax_state = SNTX_SP;
        get_token();
    }
}

void print_Tab(int n)
{
    int i = 0;
    for (; i < n; i++)
    {
        printf("\t");
    }
}

/*
语法缩进功能
*/
void syntax_indent()
{
    switch (syntax_state)
    {
    case SNTX_NUL:
        color_token(LEX_NORMAL);
        break;
    case SNTX_SP:
        printf(" ");
        color_token(LEX_NORMAL);
        break;
    case SNTX_LF_HT:
    {
        if (token == TK_END)
        {
            syntax_level--;
        }
        printf("\n");
        print_Tab(syntax_level);
    }
        color_token(LEX_NORMAL);
        break;
    case SNTX_DELAY:
        break;
    }
    syntax_state = SNTX_NUL;
}

/*
类型区分 = int,char,short,void,struct
*/
int type_specifier(Type *type)
{
    int t, type_found;
    Type type1;
    t = 0;
    type_found = 0;
    switch (token)
    {
    case KW_CHAR:
        t = T_CHAR;
        type_found = 1;
        syntax_state = SNTX_SP;
        get_token();
        break;
    case KW_SHORT:
        t = T_SHORT;
        type_found = 1;
        syntax_state = SNTX_SP;
        get_token();
        break;
    case KW_VOID:
        t = t_VOID;
        type_found = 1;
        syntax_state = SNTX_SP;
        get_token();
        break;
        type_found = 1;
        syntax_state = SNTX_SP;
        get_token();
        break;
    case KW_INT:
        t = T_INT;
        type_found = 1;
        syntax_state = SNTX_SP;
        get_token();
        break;
    case KW_STRUCT:
        t = T_STRUCT;
        syntax_state = SNTX_SP;
        struct_specifier(&type1);
        type->ref=type1.ref;
        type_found = 1;
        break;
    default:
        break;
    }
    type->t = t;
    return type_found;
}

/*
参数表达式列表
(int a,int b)
*/
void argument_expression_list()
{
    get_token();
    if (token != TK_CLOSEPA) //)
    {
        for (;;)
        {
            assignment_expression();
            if (token == TK_CLOSEPA)
            {
                break;
            }
            skip(TK_COMMA); //,
        }
    }
    skip(TK_CLOSEPA);
}

/*
初值表达式,不太懂
*/
void primary_expression()
{
    int t, addr;
    Type type;
    Symbol *s;
    switch (token)
    {
    case TK_CINT:
    case TK_CCHAR:
        get_token();
        break;
    case TK_CSTR:
        t=T_CHAR;
        type.t=t;
        // mk_pointer(&type);
        type.t |=T_ARRAY;
        var_sym_put(&type,SC_GLOBAL,0,addr);
        initializer(&type);
        // get_token();
        break;
    case TK_OPENPA: //(
        get_token();
        expression();
        skip(TK_CLOSEPA); //)
        break;
    default:
        t = token;
        get_token();
        if (t < TK_IDENT)
        {
            expect("标识符或常量");
        }
        s=sym_search(t);
        if (!s){
            if(token != TK_OPENPA){
                errorMsg("'%s'未声明\n",get_tkstr(t));
            }
            s=func_sym_push(t,&default_func_type);  //允许函数不声明，直接引用
            s->r=SC_GLOBAL|SC_SYM;
        }
        break;
    }
}

/*
后缀表达式
*/
void postfix_expression()
{
    primary_expression();
    while (1)
    {
        if (token == TK_DOT || token == TK_POINTSTO)
        { // a. a->
            get_token();
            token |= SC_MEMBER;
            get_token();
        }
        else if (token == TK_OPENBR)
        { // a[表达式]
            get_token();
            expression();
            skip(TK_CLOSEBR);
        }
        else if (token == TK_OPENPA) // a(int a,int b)
        {
            argument_expression_list();
        }
        else
        {
            break;
        }
    }
}

/*
sizeof 表达式
= sizeof(类型)
*/
void sizeof_expression()
{
    int align, size;
    Type type;
    get_token();
    skip(TK_OPENPA); //(
    type_specifier(&type);
    skip(TK_CLOSEPA); // )

    size = type_size(&type, &align);
    if (size < 0)
    {
        errorMsg("sizeof计算类型尺寸失败");
    }
}

/*
功能:返回类型长度
*t:数据类型指针
*a:对齐值
*/
int type_size(Type *t, int *a)
{
    Symbol *s;
    int bt;
    // 指针类型长度为4字节
    int PTR_SIZE = 4;
    bt = t->t & T_BTYPE;
    switch (bt)
    {
    case T_STRUCT:
        s = t->ref;
        *a = s->r;
        return s->c;
    case T_PTR:
        if (t->t & T_ARRAY)
        {
            s = t->ref;
            return type_size(&s->type, a) * s->c;
        }
        else
        {
            *a = PTR_SIZE;
            return PTR_SIZE;
        }
    case T_INT:
        *a = 4;
        return 4;
    case T_SHORT:
        *a = 2;
        return 2;
    default: // char,void ,function
        *a = 1;
        return 1;
    }
}

/*
一元表达式
= 后缀表达式
|& 一元表达式
|* 一元表达式
|- 一元表达式
|+ 一元表达式
*/
void unary_expression()
{
    switch (token)
    {
    case TK_AND:
    case TK_STAR:
    case TK_PLUS:
    case TK_MINUS:
        get_token();
        unary_expression();
        break;
    case KW_SIZEOF:
        sizeof_expression();
        break;
    default:
        postfix_expression();
        break;
    }
}

/*
乘除表达式
= 一元表达式  *|/|%  一元表达式
*/
void multiplicative_expression()
{
    unary_expression();
    while (token == TK_STAR || token == TK_DIVIDE || token == TK_MOD) // */%
    {
        get_token();
        unary_expression();
    }
}

/*
加减类表达式
=乘除类表达式
+|-
乘除类表达式
*/
void additive_expression()
{
    multiplicative_expression();
    while (token == TK_PLUS || token == TK_MINUS)
    {
        get_token();
        multiplicative_expression();
    }
}

/*
关系表达式
*/
void relational_expression()
{
    additive_expression();
    while (token == TK_LT || token == TK_LEQ ||
           token == Tk_GT || token == TK_GEQ)
    {
        get_token();
        additive_expression();
    }
}

/*
相等类表达式
=关系表达式 等于 关系表达式
或者
关系表达式 不等于 关系表达式
*/
void equality_expression()
{
    relational_expression();
    while (token == TK_EQ || token == TK_NEQ)
    {
        get_token();
        relational_expression();
    }
}

/*
赋值表达式
a=6; 等
*/
void assignment_expression()
{
    equality_expression();
    if (token == TK_ASSIGN)
    {
        get_token();
        assignment_expression();
    }
}

/*
表达式
赋值表达式,赋值表达式
int a=3,b=4;
*/
void expression()
{
    while (1)
    {
        assignment_expression();
        if (token != TK_COMMA) //,逗号
        {
            break;
        }
        get_token();
    }
}

/*
返回语句
return ;
return 表达式;
*/
void return_statement()
{
    syntax_state = SNTX_DELAY;
    get_token();
    if (token == TK_SEMICOLON) // return ;
    {
        syntax_state = SNTX_NUL;
    }
    else // return 表达式;
    {
        syntax_state = SNTX_SP;
    }
    syntax_indent();
    if (token != TK_SEMICOLON)
    {
        expression(); //  表达式
    }
    syntax_state = SNTX_LF_HT;
    skip(TK_SEMICOLON); // 忽略;
}

/*
break语句
break;
*/
void break_statement()
{
    get_token();
    syntax_state = SNTX_LF_HT;
    skip(TK_SEMICOLON); //;结束
}

/*
continue语句
continue;
*/
void continue_statement()
{
    get_token();
    syntax_state = SNTX_LF_HT;
    skip(TK_SEMICOLON); //;
}

/*
for循环语句
for(表达式陈述;表达式陈述;表达式){

}
*/
void for_statement()
{
    get_token();
    skip(TK_OPENPA);           //(
    if (token != TK_SEMICOLON) // 用;分割
    {
        expression(); // 第一个表达式
    }
    skip(TK_SEMICOLON); // ；分割
    if (token != TK_SEMICOLON)
    {
        expression(); // 第二个表达式
    }
    skip(TK_SEMICOLON);      // ；
    if (token != TK_CLOSEPA) //)
    {
        expression();
    }
    syntax_state = SNTX_LF_HT;
    skip(TK_CLOSEPA); //)
    statement();      //{}
}

/*
if 表达式= if(表达式)陈述 [else 陈述]
*/
void if_statement()
{
    syntax_state = SNTX_SP;
    get_token();
    skip(TK_OPENPA); //(
    expression();
    syntax_state = SNTX_LF_HT;
    skip(TK_CLOSEPA);     //)
    statement();          //{}
    if (token == KW_ELSE) // else
    {
        syntax_state = SNTX_LF_HT;
        get_token();
        statement(); //{}
    }
}

/*
表达式语句
= ;|表达式;
*/
void expression_statement()
{
    if (token != TK_SEMICOLON) //;结束符
    {
        expression();
    }
    syntax_state = SNTX_LF_HT;
    skip(TK_SEMICOLON);
}

/*
判断是否为类型区分符
*/
int is_type_specifier(int v)
{
    switch (v)
    {
    case KW_CHAR:
    case KW_SHORT:
    case KW_INT:
    case KW_VOID:
    case KW_STRUCT:
        return 1;
    default:
        break;
    }
    return 0;
}

/*
复合语句
={
    定义
    陈述
}

*/
void compound_statement(int *bsym, int *csym)
{
    Symbol *s;
    s = (Symbol *)stack_get_top(&local_sym_stack);
    syntax_state = SNTX_LF_HT;
    syntax_level++;
    get_token();
    while (is_type_specifier(token))
    {
        external_declaration(SC_LOCAL);
    }
    while (token != TK_END) // 假如不是}
    {
        statement(bsym, csym);
    }
    syntax_state = SNTX_LF_HT;
    sym_pop(&local_sym_stack, s);
    get_token();
}

/*
语句 =复合语句
|if语句
|return 语句
|break语句
|continue语句
|for语句
|表达式
*/
void statement()
{
    switch (token)
    {
    case TK_BEGIN:
        compound_statement(NULL,NULL);
        break;
    case KW_IF:
        if_statement();
        break;
    case KW_RETURN:
        return_statement();
        break;
    case KW_BREAK:
        break_statement();
        break;
    case KW_CONTINUE:
        continue_statement();
        break;
    case KW_FOR:
        for_statement();
        break;
    default:
        expression_statement();
        break;
    }
}

/*
初始值
比如
a=4*6
*/
void initializer(Type *type)
{
    if (type->t & T_ARRAY)
    {
        get_token();
    }
    else
    {
        assignment_expression();
    }
}

/*
函数体
{

}
*/
void funcbody(Symbol *sym)
{
    /*放一匿名符号在局部符号表中*/
    sym_direct_push(&local_sym_stack, SC_ANOM, &int_type, 0);
    compound_statement(NULL,NULL);
    /*清空局部符号栈*/
    sym_pop(&local_sym_stack, NULL);
}
/*
形参列表
格式
（参数类型1 参数1,参数类型2 参数2,参数类型n ...）

*/
void parameter_type_list(Type *type, int func_call)
{
    int n;
    Symbol **plast, *s, *first;
    Type pt;
    get_token();
    first = NULL;
    plast = &first;
    while (token != TK_CLOSEPA) // 不等于)
    {
        if (!type_specifier(&pt)) // 如int
        {
            errorMsg("%s", "无效类型标识符");
        }
        declarator(&pt, &n, NULL); // 如a
        s = sym_push(n | SC_PARAMS, &pt, 0, 0);
        *plast = s;
        plast = &s->next;
        if (token == TK_CLOSEPA) // 等于)
        {
            break;
        }
        skip(TK_COMMA);           // 假如是,
        if (token == TK_ELLIPSIS) // 假如是...，多个参数
        {
            func_call = KW_CDECL;
            get_token();
            break;
        }
    }
    syntax_state = SNTX_DELAY;
    skip(TK_CLOSEPA);      // 忽略)
    if (token == TK_BEGIN) // 假如是{也就是函数体的开始
    {                      // 函数定义
        syntax_state = SNTX_LF_HT;
    }
    else
    {
        syntax_state = SNTX_NUL;
    }
    syntax_indent();

    // 此处将函数返回类型存储，然后指向参数，最后将type设为函数类型，引用的
    // 相关信息放在ref中
    s = sym_push(SC_ANOM, type, func_call, 0);
    s->next = first;
    type->t = T_FUNC;
    type->ref = s;
}

/*
直接声明符后缀
int a[5] ; [5]就是直接声明符后缀
a(); ()也是直接声明符后缀
a(int a,int b) (int a,int b)也是直接声明符后缀
a[] []也是直接声明符后缀
*/
void direct_declarator_postfix(Type *type, int func_call)
{
    int n;
    Symbol *s;
    if (token == TK_OPENPA) //(
    {                       // (int a,int b)
        parameter_type_list(type, func_call);
    }
    else if (token == TK_OPENBR) //[
    {                            // a[5][8]
        get_token();
        n = -1;
        if (token == TK_CINT)
        {
            get_token();
            n = tkvalue;
        }
        skip(TK_CLOSEBR);
        direct_declarator_postfix(type, func_call);
        s = sym_push(SC_ANOM, type, 0, n);
        type->t = T_ARRAY | T_PTR;
        type->ref = s;
    }
}

/*
直接声明符 int a  a就是直接声明符号 int a[5] a也是直接声明符号
*/
void direct_declarator(Type *type, int *v, int func_call)
{
    if (token >= TK_IDENT)
    {
        *v = token;
        get_token();
    }
    else
    {
        expect("标志符");
    }
    direct_declarator_postfix(type, func_call);
}

/*
结构体成员对齐 __align(8)
*/
void struct_member_alignment(int *force_align)
{
    int align = 1;
    if (token == KW_ALIGN)
    {
        get_token();
        skip(TK_OPENPA); //(左括号
        if (token == TK_CINT)
        {
            get_token();
            align = tkvalue;
        }
        else
        {
            expect("整数常量");
        }
        skip(TK_CLOSEPA);
        if (align != 1 && align != 2 && align != 4)
        {
            align = 1;
        }
        align |= ALIGN_SET;
        *force_align = align;
    }
    else
    {
        *force_align = 1;
    }
}

/*
声明符  int **a a就是声明符号
*/
void declarator(Type *type, int *v, int *force_align)
{
    int fc;
    while (token == TK_STAR) //*号，可以是***
    {
        // mk_pointer(type);
        get_token();
    }
    function_calling_convention(&fc);
    if (force_align)
    {
        struct_member_alignment(force_align);
    }
    direct_declarator(type, v, fc);
}

/*
结构声明=
*/
void struct_declaration(int *maxalign, int *offset, Symbol ***ps)
{
    int v, size, align;
    Symbol *ss;
    Type type1, btype;
    int force_align;
    type_specifier(&btype);
    while (1)
    {
        v = 0;
        type1 = btype;
        declarator(&type1, &v, &force_align);
        size = type_size(&type1, &align);

        if (force_align & ALIGN_SET)
        {
            align = force_align & ~ALIGN_SET;
        }

        *offset = calc_align(*offset, align);

        if (align > *maxalign)
        {
            *maxalign = align;
        }
        ss = sym_push(v | SC_MEMBER, &type1, 0, *offset);
        *offset += size;
        **ps = ss;
        *ps = &ss->next;

        if (token == TK_SEMICOLON) // 假如遇到分号;，就说明结束了struct a{};
        {
            break;
        }
        skip(TK_COMMA); // 忽略,号,这结构体里面用,如int a,b;
    }
    syntax_state = SNTX_LF_HT;
    skip(TK_SEMICOLON);
}

/*
功能:计算字节对齐位置
n:未对齐前值
align:对齐粒度
*/
int calc_align(int n, int align)
{
    return ((n + align - 1) & (~(align - 1)));
}

/*
结构体定义列表=结构体定义或者没有
*/
void struct_declaration_list(Type *type)
{
    int maxalign, offset;
    Symbol *s, **ps;
    s = type->ref;
    syntax_state = SNTX_LF_HT; // 第一个结构体成员与'{'不写同一行
    syntax_level++;            // 结构体成员变量声明，缩进增加一级
    get_token();
    if (s->c != -1)
    { // s->c记录结构体尺寸
        errorMsg("结构体已定义");
    }
    maxalign = 1;
    ps = &s->next;
    offset = 0;
    while (token != TK_END) // 不是}的时候
    {
        struct_declaration(&maxalign, &offset, &ps);
    }
    skip(TK_END);
    syntax_state = SNTX_LF_HT;
    s->c = calc_align(offset, maxalign); // 结构体大小
    s->r = maxalign;                     // 结构体对齐
}

/*
结构体 = struct 定义{结构体定义列表}|struct 定义
*/
void struct_specifier(Type *type)
{
    int v;
    Symbol *s;
    Type type1;
    get_token();
    v = token;
    syntax_state = SNTX_DELAY; // 延迟取出下一个单词后确定输出格式
    get_token();
    if (token == TK_BEGIN)
    { // 适用于结构体定义 struct 结构体名 {
        syntax_state = SNTX_LF_HT;
    }
    else if (token == TK_CLOSEPA)
    { // 适用于sizeof(struct struct_name)
        syntax_state = SNTX_NUL;
    }
    else
    { // 适用于结构变量声明，如struct 结构体名 变量名;
        syntax_state = SNTX_SP;
    }
    syntax_indent();
    if (v < TK_IDENT)
    { // 关键字不能作为结构体名称
        expect("结构体名");
    }
    s = struct_search(v);
    if (!s)
    {
        type1.t = KW_STRUCT;
        // -1赋值给s->c,标志结构体尚未定义
        s = sym_push(v | SC_STRUCT, &type1, 0, -1);
        s->r = 0;
    }
    type->t = T_STRUCT;
    type->ref = s;
    if (token == TK_BEGIN)
    {
        struct_declaration_list(type); // 结构体定义列表，结构体里面的数据
    }
}

void external_declaration(int l)
{
    Type btype, type;
    int v, has_init, r, addr;
    Symbol *sym;
    if (!type_specifier(&btype))
    {
        expect("<类型区分符>");
    }
    if (btype.t = T_STRUCT && token == TK_SEMICOLON)
    {
        get_token();
        return;
    }
    while (1)
    {
        type = btype;
        declarator(&type, &v, NULL);
        if (token == TK_BEGIN)
        {
            if (l == SC_LOCAL)
            {
                errorMsg("%s", "不支持函数嵌套定义");
            }
            if ((type.t & T_BTYPE) != T_FUNC)
            {
                except("<函数定义>");
            }
            sym = sym_search(v);
            if (sym)
            { // 函数前面声明过，现在给出函数定义
                if ((sym->type.t & T_BTYPE) != T_FUNC)
                {
                    errorMsg("‘%s’重定义", get_tkstr(v));
                }
                sym->type = type;
            }
            else
            {
                sym = func_sym_push(v, &type);
            }
            sym->r = SC_SYM | SC_GLOBAL;
            funcbody(sym);
            break;
        }
        else
        {
            if ((type.t & T_BTYPE) == T_FUNC)
            { // 函数声明
                if (sym_search(v) == NULL)
                {
                    sym = sym_push(v, &type, SC_GLOBAL | SC_SYM, 0);
                }
            }
            else
            { // 变量声明
                r = 0;
                if (!(type.t & T_ARRAY))
                {
                    r |= SC_LVAL;
                }
                r |= l;
                has_init = (token == TK_ASSIGN);
                if (has_init)
                {
                    get_token();
                    initializer(&type);
                }
                sym = var_sym_put(&type, r, v, addr);
            }
            if (token == TK_COMMA)
            {
                get_token();
            }
            else
            {
                syntax_state = SNTX_LF_HT;
                skip(TK_SEMICOLON);
                break;
            }
        }
    }
}

void translation_unit()
{
    while (token != TK_EOF)
    {
        external_declaration(SC_GLOBAL);
    }
}